#include "D3D9Effect.h"
#include "D3D9Device.h"
#include "D3D9Texture.h"
#include "ITexture.h"
//! sharpShooter
namespace sharpShooter
{
	//! Render
	namespace Render
	{
		EResult CD3D9Effect::loadEffectFromFile(const std::string filePath)
		{

			if (filePath.empty())
			{
				return E_ResultParamNotAvailable;
			}

			DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
			dwShaderFlags |= D3DXSHADER_DEBUG;
#ifdef DEBUG_VS
			dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
#endif
#ifdef DEBUG_PS
			dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
#endif
			HRESULT hr = D3DXCreateEffectFromFileA(m_pD3D9Device,filePath.c_str(),NULL,NULL,dwShaderFlags,NULL,&m_pD3DEffect,NULL);
			if (!SUCCEEDED(hr))
			{
				return E_ResultFailed;
			}
			
			return E_ResultSuccessed;
		}

		EResult CD3D9Effect::loadEffectFromString(const std::string effectSource)
		{
			if (effectSource.empty())
			{
				return E_ResultParamNotAvailable;
			}
			DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
			dwShaderFlags |= D3DXSHADER_DEBUG;
#ifdef DEBUG_VS
			dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
#endif
#ifdef DEBUG_PS
			dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
#endif
			HRESULT hr = D3DXCreateEffect(m_pD3D9Device,effectSource.c_str(),(UINT)effectSource.length(),NULL,NULL,dwShaderFlags,NULL,&m_pD3DEffect,NULL);
			
			if (!SUCCEEDED(hr))
			{
				return E_ResultFailed;
			}

			return E_ResultSuccessed;
		
		}

		EResult CD3D9Effect::setFloat( std::string paramName, float floatValue )
		{
			D3DXHANDLE handle = m_pD3DEffect->GetParameterByName(0, paramName.c_str());
			HRESULT hr = m_pD3DEffect->SetFloat(handle, floatValue);
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::setVector4f( std::string paramName, const Core::Vector4f &vector4f )
		{
			D3DXVECTOR4 d3dVector4f;
			setD3DVector4(d3dVector4f, vector4f);
			D3DXHANDLE handle = m_pD3DEffect->GetParameterByName(0, paramName.c_str());
			HRESULT hr = m_pD3DEffect->SetVector(handle, &d3dVector4f);
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::setMatrix4f( std::string paramName, const Core::Matrix4f &matrix4f )
		{
			D3DXMATRIX d3dMatrix4f;
			setD3DMatrix(d3dMatrix4f, matrix4f);
			D3DXHANDLE handle = m_pD3DEffect->GetParameterByName(0, paramName.c_str());
			HRESULT hr = m_pD3DEffect->SetMatrix(handle, &d3dMatrix4f);
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::setTexture( std::string paramName, TexturePtr texture )
		{
			D3DXHANDLE handle = m_pD3DEffect->GetParameterByName(0, paramName.c_str());
			D3D9Texture *pD3DTexture = dynamic_cast<D3D9Texture*>(texture);
			HRESULT hr = m_pD3DEffect->SetTexture(handle, pD3DTexture->getD3D9Texture());
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::Begin( unsigned int *passes, unsigned long flag)
		{
			HRESULT hr = m_pD3DEffect->Begin(passes, flag);
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::BeginPass( unsigned int pass )
		{
			HRESULT hr = m_pD3DEffect->BeginPass(pass);
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::CommitChanges( void )
		{
			HRESULT hr = m_pD3DEffect->CommitChanges();
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::EndPass( void )
		{
			HRESULT hr = m_pD3DEffect->EndPass();
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		EResult CD3D9Effect::End( void )
		{
			HRESULT hr = m_pD3DEffect->End();
			return SUCCEEDED(hr) ? EResult(E_ResultSuccessed) : EResult(E_ResultFailed);
		}

		CD3D9Effect::CD3D9Effect(IDirect3DDevice9 *pDevice )
			:m_pD3D9Device(pDevice),m_pD3DEffect(NULL)
		{		
		}

		CD3D9Effect::~CD3D9Effect()
		{
			SAFE_RELEASE(m_pD3DEffect);
		}
	}
}